package Helper

import (
	"bytes"
	"compress/gzip"
	"encoding/base64"
	"fmt"
	"go/ast"
	"gt.jtthink.com/AstParser"
	"io/ioutil"
	"log"
	"strings"
	"text/template"
)
//给模板使用的函数集
func NewTplFunction() template.FuncMap  {
	fm:=make(map[string]interface{})
	fm["CamelCase"]=CamelCase
	fm["SnakeCase"]=SnakeCase
	fm["Ucfirst"]=Ucfirst
	fm["MakeServiceName"]=MakeServiceName
	fm["MakeParams"]=MakeParams
	fm["MakeImports"]=MakeImports
	fm["MakeResults"]=MakeResults
	fm["Gzip"]=Gzip
	fm["MapType"]=MapDBType
	fm["RemoveTablePrefix"]=RemoveTablePrefix
	return fm
}
//生成Service名称。 一般规则是接口名+Impl
func MakeServiceName(sname string) string{
	return CamelCase(sname)+"Impl"
}
//解析函数参数
func MakeParams(pps []*AstParser.PParam) string  {
	ret:=""
	 //处理map 的函数
	mapFilter:=func(pp *AstParser.PParam) *AstParser.PParam{
		 if pp.IsMap{
		 	mapCut:=strings.Split(pp.Type,".")
		 	if len(mapCut)>=2{ //map类型至少2个长度。如string.int
		 	format_str:=""
		 	valCut:=make([]interface{},0)
		 	for index,mc:=range mapCut{ //这一步为了构建format
		 		valCut=append(valCut,mc)
					if index==len(mapCut)-1{
						format_str+="%s"
					}else {
						format_str+="map[%s]"
					}
			}
		 	 pp.Type=fmt.Sprintf(format_str,valCut...)
			}
		 }
		 return pp
	}
	for index,p:=range pps{
		if index!=0{
			ret+=","
		}
		ret+=fmt.Sprintf("%s %s %s%s%s",p.Name,p.If(AstParser.PARAM_ISCHAN,"chan"),
			p.If(AstParser.PARAM_ISARRAY,"[]"),
			p.If(AstParser.PARAM_ISPTR,"*"),mapFilter(p).Type)
	}
	return ret

}

//解析返回值参数
func MakeResults(pps []*AstParser.PParam) string{
	 ret:=MakeParams(pps)
	 if len(pps)>1{
	 	return "("+ret+")"
	 }
	 return ret
}
//解析imports
func MakeImports(impts []*ast.ImportSpec) string{
	if len(impts)==0{
		return ""
	}
	name:= func(n *ast.Ident) string  {
		if n!=nil{
			return n.Name
		}
		return ""
	}

	if len(impts)==1{
		return fmt.Sprintf("import %s%s",name(impts[0].Name),impts[0].Path.Value)
	}
	ret:="import (\n"
	for _,impt:=range impts{
		ret+=fmt.Sprintf(" %s%s\n",name(impt.Name),impt.Path.Value)
	}
	ret+=")\n"
	return  ret
}

func Gzip(str string) string{
	var buf bytes.Buffer
	gz := gzip.NewWriter(&buf)
	_, err := gz.Write([]byte(str))
	if err != nil {
		log.Println(err)
		return ""
	}
	 err=gz.Close() //这里要关掉，否则取不到数据  也可手工flush.但依然要关掉gz
	if err != nil {
		log.Println(err)
		return ""
	}
	return base64.StdEncoding.EncodeToString(buf.Bytes())
}
func UnGzip(str string) string{
	dbytes,err:=base64.StdEncoding.DecodeString(str)
	if err != nil {
		log.Println(err)
		return ""
	}
	read_data:=bytes.NewReader(dbytes)
	reader, err := gzip.NewReader(read_data)
	if err != nil {
		log.Println(err)
		return ""
	}
	defer reader.Close()
    ret,err:=ioutil.ReadAll(reader)
	if err != nil {
		log.Println("read gzip error:",err)
		return ""
	}

	return string(ret)

}

